﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace Super
{
	public static class LangUtil
	{
		/// <summary>
		/// 获取所有的多语言keys
		/// 自定义keys和excel表格中的keys
		/// </summary>
		/// <returns></returns>
		public static HashSet<string> GetKeys()
		{
			HashSet<string> result = GetKeysByAA(FWConfig.excelLangKeyPath);
			HashSet<string> customLangs = GetKeysByAA(FWConfig.customLangKeyPath);
			result.UnionWith(customLangs);
			return result;
		}

		/// <summary>
		/// 获取多语言keys通过指定的AName（addressable资源文件的索引名称）
		/// </summary>
		/// <param name="AName"></param>
		/// <returns></returns>
		public static HashSet<string> GetKeysByAA(string AName)
		{
			HashSet<string> result = new HashSet<string>();
			if (!AssetUtil.AExist(AName))
			{
				return result;
			}

			TextAsset textAsset = AssetUtil.ALoadAsset<TextAsset>(AName);
			string[] lines = textAsset.text.Split("\n");
			string line;
			for (int i = 0; i < lines.Length; i++)
			{
				line = lines[i].TrimStart();
				if (line.StartsWith("#") || string.IsNullOrEmpty(line) || line == "\r" || line.Contains("="))
				{
					continue;
				}

				result.Add(line.Replace("\r", ""));
			}
			return result;
		}



		/// <summary>
		/// 获取AA文件中的数据信息，文件中的keys，以及键值对的翻译信息
		/// </summary>
		/// <param name="AName"></param>
		/// <returns></returns>
		public static LangDataInfo GetDataInfoByAA(string AName)
		{
			TextAsset textAsset = AssetUtil.ALoadAsset<TextAsset>(AName);
			string[] lines = textAsset.text.Split("\n");
			return GetDataInfoByLines(lines);
		}

		/// <summary>
		/// 获取文件中的数据信息，文件中的keys，以及键值对的翻译信息
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		public static LangDataInfo GetDataInfoByPath(string path)
		{
			path = GlobalUtil.GetAbsolutePath(path);
			StreamReader SR = new StreamReader(path);
			string[] lines = SR.ReadToEnd().Split("\n");
			SR.Close();
			return GetDataInfoByLines(lines);
		}

		/// <summary>
		/// 获取'行数组'中的数据信息，文件中的keys，以及键值对的翻译信息
		/// </summary>
		/// <param name="lines"></param>
		/// <returns></returns>
		private static LangDataInfo GetDataInfoByLines(string[] lines)
		{
			LangDataInfo info = new LangDataInfo();
			string line;
			string[] keyValues;
			for (int i = 0; i < lines.Length; i++)
			{
				line = lines[i].TrimStart();
				if (line.StartsWith("#") || string.IsNullOrEmpty(line) || line == "\r")
				{
					continue;
				}
				line = line.Replace("\r", "");
				keyValues = line.Split("=");
				if (keyValues.Length > 1)
				{
					info.keyValuePairs[keyValues[0]] = keyValues[1];
				}
				info.keys.Add(keyValues[0]);
			}
			return info;
		}



		/// <summary>
		/// 添加多语言key|追加写入
		/// </summary>
		/// <param name="key"></param>
		/// <param name="path">多语言文件的路径</param>
		/// <param name="templateAName">多语言文件创建时的模板AA</param>
		public static void AddKey(string key, string path, string templateAName = null)
		{
			HashSet<string> keys = new HashSet<string> { key };
			AddKeys(keys, path, templateAName);
		}

		/// <summary>
		/// 添加多语言keys|追加写入
		/// </summary>
		/// <param name="keys"></param>
		/// <param name="path">多语言文件的路径</param>
		/// <param name="templateAName">多语言文件创建时的模板AA</param>
		public static void AddKeys(HashSet<string> keys, string path, string templateAName = null)
		{
#if UNITY_EDITOR
			path = GlobalUtil.GetAbsolutePath(path);
			string content = templateAName == null ? "" : AssetUtil.ALoadAsset<TextAsset>(templateAName).text;
			bool isCreated = AssetUtil.TryCreatDirectoryAndFile(path, content);
			if (isCreated)
			{
				AssetUtil.ACreateOrMove(FWConfig.textAGroup, path);
			}
			StreamWriter SW = new StreamWriter(path, true);
			SW.AutoFlush = true;
			foreach (var key in keys)
			{
				SW.WriteLine();
				SW.Write(key);
			}
			SW.Flush();
			SW.Close();
			AssetDatabase.Refresh();
#endif
		}

		/// <summary>
		/// 保存Keys|覆盖写入
		/// </summary>
		/// <param name="langKeys"></param>
		/// <param name="AName"></param>
		private static void SaveLangKeys(HashSet<string> langKeys, string AName)
		{
			string path = GlobalUtil.GetAbsolutePath(AName);
			bool isCreated = AssetUtil.TryCreatDirectoryAndFile(path);
			if (isCreated)
			{
				AssetUtil.ACreateOrMove(FWConfig.textAGroup, AName);
			}
			StreamWriter streamWriter = new StreamWriter(path);
			streamWriter.AutoFlush = true;
			foreach (var key in langKeys)
			{
				streamWriter.WriteLine(key);
			}
			streamWriter.Flush();
			streamWriter.Close();
		}


		/// <summary>
		/// 尝试生成自定义多语言文件,文件已存在则忽略
		/// </summary>
		/// <returns></returns>
		public static bool TryGenerateCustomFile()
		{
			string path = GlobalUtil.GetAbsolutePath(FWConfig.customLangKeyPath);
			TextAsset textAsset = AssetUtil.ALoadAsset<TextAsset>(FWConfig.templateCustomLangKeys);
			bool isCreated = AssetUtil.TryCreatDirectoryAndFile(path, textAsset.text);
			if (isCreated)
			{
				AssetUtil.ACreateOrMove(FWConfig.textAGroup, FWConfig.customLangKeyPath);
#if UNITY_EDITOR
				AssetDatabase.Refresh();
#endif

			}
			return isCreated;
		}

		/// <summary>
		/// 生成Keys文件，包含自定义和excel相关的keys集合
		/// </summary>
		public static void GenerateKeysFile()
		{
#if UNITY_EDITOR
			HashSet<string> langKeys = GetKeys();
			SaveLangKeys(langKeys, FWConfig.langKeysPath);
			AssetDatabase.Refresh();
			string logInfo = $"生成新LangKeys文件\n" +
				$"<a href=\"{FWConfig.langKeysPath}\">文件链接</a>";
			LogUtil.Log(LogType.Normal, LogCategory.Lang, logInfo);
#endif
		}



		/// <summary>
		/// 生成Excel相关的多语言文件
		/// </summary>
		public static void GenerateAllExcelFile()
		{
#if UNITY_EDITOR
			HashSet<string> langSet = new HashSet<string>();
			foreach (var item in ExcelNoteSO.Ins.Notes)
			{
				ExcelNoteNode node = ExcelNoteSO.Ins.FindTableInfo(item.excelPath);
				for (int i = 0; i < node.TableNames.Count; i++)
				{
					ExcelTableInfo info = ExcelUtil.GetTableInfo(node.excelPath, i);
					if (info.hasLang)
					{
						langSet.UnionWith(GetExcelKeys(info));
						LogUtil.Log(LogType.Normal, LogCategory.Lang, $"{item.excelPath}_{item.TableNames[i]} 表格多语言处理");
					}
				}
			}
			SaveLangKeys(langSet, FWConfig.excelLangKeyPath);
			AssetDatabase.Refresh();
			LogUtil.Log(LogType.Normal, LogCategory.Lang, "生成ExcelLang文件");
#endif
		}

		/// <summary>
		/// 获取Excel配置中新的Keys集合，与之前所有Keys相比较
		/// </summary>
		/// <param name="info"></param>
		/// <param name="langSet"></param>
		public static HashSet<string> GetExcelNewKeys(ExcelTableInfo info)
		{
			HashSet<string> langSet = new HashSet<string>();
			HashSet<string> oldLangs = GetKeys();
			string[][] allRowData = info.data.Skip(info.ignoreRow).ToArray();
			foreach (var rowData in allRowData)
			{
				string[] data = rowData.Skip(info.ignoreCol).ToArray();
				foreach (var index in info.langFieldIndexs)
				{
					if (!oldLangs.Contains(data[index]))
					{
						langSet.Add(data[index]);
					}
				}
			}
			return langSet;
		}

		/// <summary>
		/// 获取Excel中的Keys集合
		/// </summary>
		/// <param name="info"></param>
		/// <returns></returns>
		public static HashSet<string> GetExcelKeys(ExcelTableInfo info)
		{
			HashSet<string> langSet = new HashSet<string>();
			string[][] allRowData = info.data.Skip(info.ignoreRow).ToArray();
			foreach (var rowData in allRowData)
			{
				string[] data = rowData.Skip(info.ignoreCol).ToArray();
				foreach (var index in info.langFieldIndexs)
				{
					langSet.Add(data[index]);
				}
			}
			return langSet;
		}


		
		/// <summary>
		/// 获取当前多语言文件的路径或者AddressableName
		/// </summary>
		/// <returns></returns>
		public static string GetCurPathOrAName()
		{
			if (LangManager.GetCurIndex() == 0)
			{
				return FWConfig.customLangKeyPath;
			}
			else
			{
				LangFileInfo langFileInfo = LangManager.FileList[LangManager.GetCurIndex()];
				if (langFileInfo.isCustom)
				{
					return langFileInfo.absolutePath;
				}
				else
				{
					return langFileInfo.AName;
				}
			}
		}


		/// <summary>
		/// 加载多语言文件
		/// </summary>
		/// <returns></returns>
		public static List<LangFileInfo> LoadFileList()
		{
			List<LangFileInfo> fileList = new List<LangFileInfo>();
			LangFileInfo langFileInfo = new LangFileInfo();
			langFileInfo.name = "default";
			fileList.Add(langFileInfo);   //第一个为默认语言
			LoadLocalLang(fileList);
			TryLoadCustomLang(fileList);
			return fileList;
		}

		/// <summary>
		/// 加载本地多语言文件
		/// </summary>
		/// <param name="langList"></param>
		private static void LoadLocalLang(List<LangFileInfo> langList)
		{
			List<TextAsset> textAssets = AssetUtil.ALoadAssets<TextAsset>(FWConfig.LangsDirectory);
			foreach (TextAsset textAsset in textAssets)
			{
				if (textAsset != null && textAsset.name.StartsWith("Lang"))
				{
					LangFileInfo langFileInfo = new LangFileInfo();
					langFileInfo.name = textAsset.name.Replace("Lang", "");
					langFileInfo.isCustom = false;
					string fileName = $"{textAsset.name}.txt";
					langFileInfo.AName = $"{FWConfig.LangsDirectory}/{fileName}";
					langList.Add(langFileInfo);
				}
			}
		}

		/// <summary>
		/// 尝试加载PC自定义多语言文件
		/// </summary>
		/// <param name="langList"></param>
		/// <returns></returns>
		private static bool TryLoadCustomLang(List<LangFileInfo> langList)
		{
#if UNITY_STANDALONE_WIN
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Application.dataPath, "/Lang"));
			if (!directoryInfo.Exists)
			{
				return false;
			}
			foreach (FileInfo fileInfo in directoryInfo.GetFiles())
			{
				string fileName = Path.GetFileNameWithoutExtension(fileInfo.Name);
				if (fileName.StartsWith("Lang") && fileName != "Keys")
				{
					LangFileInfo langFileInfo = new LangFileInfo();
					langFileInfo.name = fileName.Replace("Lang", "");
					langFileInfo.isCustom = true;
					langFileInfo.absolutePath = fileInfo.FullName;
					langList.Add(langFileInfo);
				}

			}
			return true;
#else
			return false;
#endif
		}

	}
}
